﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml;
using encrpt;
using lgmkr;

namespace wkwxml
{
    public class DataLayer
    {
#pragma warning disable 612,618
        static readonly string PathXml = Application.StartupPath + "\\Connecting.xml";// ConfigurationSettings.AppSettings["PathXMLData"].ToString(CultureInfo.InvariantCulture);
#pragma warning restore 612,618

        protected static LogMaker ALogMaker;
        public static string GetConfiguration()
        {
            RSA.LoadKey();
            var fs = new FileStream(PathXml, FileMode.OpenOrCreate,FileAccess.Read, FileShare.ReadWrite);
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(fs);
            string temp = String.Empty;
            string[] t = { "Server=", "Port=", "Uid=", "Persist Security Info=", "Password=", "Database="/*, "AllowZeroDatetime="*/ };
            for (int i = 0; i < xmlDoc.DocumentElement.ChildNodes.Count; i++)
            {

                for (int j = 0; j < xmlDoc.DocumentElement.ChildNodes[i].ChildNodes.Count; j++)
                {
                    temp +=t[j]+ RSA.Decrypt(xmlDoc.DocumentElement.ChildNodes[i].ChildNodes[j].InnerText) + ";";
                }
            }
            fs.Close();
            return temp;
        }
        public static ArrayList GetCurrentConfiguration()
        {
            var fs = new FileStream(PathXml, FileMode.Open,FileAccess.Read, FileShare.ReadWrite);
            RSA.LoadKey();
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(fs);
            var hostPort=new ArrayList(2);
            hostPort.Add(RSA.Decrypt(xmlDoc.DocumentElement.ChildNodes[0].SelectSingleNode("Host").InnerText));
            hostPort.Add(RSA.Decrypt(xmlDoc.DocumentElement.ChildNodes[0].SelectSingleNode("Port").InnerText));
            fs.Close();
            return hostPort;
        }
        public static bool AddConfiguration(Connection newConnection, ref string message)
        { 
            ALogMaker=new LogMaker();
            if (CheckForExistConfiguration(newConnection))
            {
                message = "Такая Конфигурацию уже имеется в базе данных";
                ALogMaker.Error = message;
                ALogMaker.PrintLog();
                return false;
            }
            FileStream fs;
            XmlDocument xmlDoc;
            try
            {
                using (fs = new FileStream(PathXml, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    xmlDoc = new XmlDocument();
                    xmlDoc.Load(fs);
                    fs.Close();
                }
            }
            catch
            {
                message = "Не удалось создать Конфигурацию. Файл БД поврежден, или отсутствует";
                ALogMaker.Error = message;
                ALogMaker.PrintLog();
                return false;
            }
            try
            {
                XmlElement newItem;
                XmlElement newOuterItem = xmlDoc.CreateElement("Connection");
                foreach (KeyValuePair<string, string> kvp in newConnection.ConnectionInfo)
                {
                    newItem = xmlDoc.CreateElement(kvp.Key);
                    newItem.InnerText = kvp.Value;
                    newOuterItem.AppendChild(newItem);
                }
                if (xmlDoc.DocumentElement != null)
                    xmlDoc.DocumentElement.InsertAfter(newOuterItem,xmlDoc.DocumentElement.LastChild);
                var writer = new FileStream(PathXml,FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
                xmlDoc.Save(writer);
                writer.Dispose();
            }
            catch
            {
                message = "Конфигурацию не удалось создать";
                ALogMaker.Error = message;
                ALogMaker.PrintLog();
                return false;
            }
            return true;
        }

        public static string UpdateConfiguration(string currentHost,string currentPort, Connection proposedConnection)
        {
            ALogMaker=new LogMaker();
            if (currentHost != proposedConnection.Host || currentPort != proposedConnection.Port)
            {
                if (CheckForExistConfiguration(proposedConnection))
                {
                    string s = "Такая конфигурация уже имеется в БД. Измените параметры конфигурации";
                    ALogMaker.Error = s;
                    ALogMaker.PrintLog();
                    return s;
                }
            }
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(PathXml);

                XmlNode root = xmlDoc.DocumentElement;
                XmlNode node = root.SelectSingleNode(String.Format(
                    "Connection[Host='{0}' and Port='{1}']", currentHost, currentPort));

                XmlNodeList list = node.ChildNodes;
                for (int i = 0; i < list.Count; i++)
                    list.Item(i).InnerText =proposedConnection.ConnectionInfo[list.Item(i).Name];

                FileStream fs = new FileStream(PathXml,
                    FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);

                xmlDoc.Save(fs);
                fs.Dispose();
                return "Конфигурация успешно обновлена, но файл с описанием не создан!";
            }
            catch
            {
                string s = "Конфигурация не обновлена";
                ALogMaker.Error = s;
                ALogMaker.PrintLog();
                return s;
            }
        }

        private static bool CheckForExistConfiguration(Connection newConnection)
        {
            XmlDocument xmlDoc;
            try
            {
                xmlDoc = new XmlDocument();
                xmlDoc.Load(PathXml);
            }
            catch
            {
                return true;
            }

            XmlNodeList xmlListName = xmlDoc.DocumentElement.GetElementsByTagName("Host");
            XmlNodeList xmlListSurName = xmlDoc.DocumentElement.GetElementsByTagName("Port");
            for (int j = 0; j < xmlListName.Count; j++)
                if (xmlListName[j].InnerText == newConnection.ConnectionInfo["Host"] &&
                    xmlListSurName[j].InnerText == newConnection.ConnectionInfo["Port"])
                    return true;

            return false;
        }
    }
}